package org.noka.bver;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.List;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.noka.gson.Gson;
import org.noka.gson.reflect.TypeToken;
import org.nokatag.password.AESPlus;
import org.nokatag.system.BugInfoWrint;
import org.nokatag.system.Concest;

/**
 * 滑动验证码服务类
 * @author rebin
 * @2015-11-30
 */
public class CodeServer {
	
	/**
	 * 创建验证码图片
	 * @param request
	 */
	public void CodeCreate(HttpServletRequest request,HttpServletResponse response){
		response.setContentType("text/json");
		response.setHeader("pragma", "no-cache");
		response.setHeader("expires","0");
		String w = request.getParameter("w");
		String h = request.getParameter("h");
		if(null!=w && null!=h){
			try{
				Integer width = Integer.parseInt(w);
				Integer height = Integer.parseInt(h);
				Random rd = new Random();
				BufferedImage image = new BufferedImage(width,height, BufferedImage.TYPE_INT_ARGB);
				Graphics g = image.getGraphics();
				g.setColor(new Color(rd.nextInt(100), rd.nextInt(100), rd.nextInt(100)));
				g.fillRect(0, 0,width,height);
				for(int i=0;i<width;i++){
					g.setColor(new Color(rd.nextInt(200), rd.nextInt(200), rd.nextInt(200)));
					g.drawLine(rd.nextInt(width), rd.nextInt(height), rd.nextInt(width), rd.nextInt(height));
				}
				//-------------生成验证纯色区域-------------------------------------
				int cr = rd.nextInt(300);//验证码
				int std = rd.nextInt(width);
				int std2 = rd.nextInt(width);
				if(std<40)
					std=40;
				if(std>width-40)
					std=width-40;
				if(std2<40)
					std=40;
				if(std2>width-40)
					std2=width-40;
				g.setColor(new Color(cr));
				g.fillRect(std, 0,30,height);
				g.fillRect(std2, 0,30,height);
				//-----------------------------------------------------------------
				g.dispose();
				ByteArrayOutputStream output = new ByteArrayOutputStream();//验证图片
				ImageIO.write(image, "jpeg",output);
				output.flush();
				output.close();
				//------------存储验证信息-----------------------------------------
				String imgStr = AESPlus.parseByte2HexStr(output.toByteArray());//图片二进制数据转成16进制字符串
				String crs = AESPlus.encrypt(String.valueOf(cr),Concest.SQLKEY);//加密验证码
				String imgEStr = AESPlus.encrypt(imgStr,Concest.SQLKEY);//加密图片字符串
				//------------生成json到前端----------------------------------
				OutputStream out = response.getOutputStream();
				Writer wr=new OutputStreamWriter(out,Concest.ENCODING);
				wr.write("{\"cr\":\""+crs+"\",\"icr\":\""+imgEStr+"\"}");
				wr.flush();
				out.flush();
				wr.close();
				out.close();
			}catch(Exception se){
				BugInfoWrint.Print(se);
			}
		}
	}
	/**
	 * js验证
	 * @param request
	 * @param response
	 */
	public void isCheckJSOn(HttpServletRequest request,HttpServletResponse response){
		try{
			response.setContentType("text/json");
			String field = "f";
			String istrue = "false";
			if(isCheck(request,field)){
				istrue="true";
			}
			OutputStream out = response.getOutputStream();
			Writer wr=new OutputStreamWriter(out,Concest.ENCODING);
			wr.write("{\"c\":"+istrue+"}");
			wr.flush();
			out.flush();
			wr.close();
			out.close();
		}catch(Exception se){
			BugInfoWrint.Print(se);
		}
	}
	/**
	 * 验证是否通过
	 * @return
	 */
	public boolean isCheck(HttpServletRequest request,String field){
		String filed = request.getParameter(field);
		String cr = request.getParameter(field+"_cr");
		String icr = request.getParameter(field+"_icr");
		if(null!=cr && null!=icr){//进入验证
			try{
				cr = AESPlus.decrypt(cr, Concest.SQLKEY);//解密
				icr = AESPlus.decrypt(icr, Concest.SQLKEY);//解密
				Color co = new Color(Integer.parseInt(cr));
				double srgp =Math.floor(co.getRGB()/100000);//色值验证码
				//--------------------------------------------------------------------------------------
				ByteArrayInputStream  input = new ByteArrayInputStream(AESPlus.parseHexStr2Byte(icr));
				BufferedImage bimg = ImageIO.read(input);
				Gson gson = new Gson();
				List<LoaItem> listItem = gson.fromJson(filed,new TypeToken<List<LoaItem>>(){}.getType());
				Integer MaxLeng = 200;
				MaxLeng = (listItem.get(listItem.size()-1).getX())/2;
				MaxLeng = MaxLeng+(MaxLeng/2);
				if(listItem.size()>MaxLeng)//大于80有可能是机器
					return false;
				Integer Ux = 0;//上一个X坐标
				Integer xs = 0;
				for(LoaItem la : listItem){
					if(la.getX()<Ux && Ux!=0){//当前X坐标比上一个X坐标还小或是相等，有可能为机器
						return false;
					}
					if(la.getX().equals(Ux-1) || la.getX().equals(Ux)){
						xs++;
					}
					if(xs>5){
						return false;
					}
					Ux = la.getX();
				}
				for(LoaItem la : listItem){
					try{
						double rgp = Math.floor(bimg.getRGB(la.getX(), la.getY())/100000);
						BugInfoWrint.Print((rgp==srgp)+"  rgp:="+rgp+"   srgp:="+srgp);
						if(rgp==srgp){//验证成功
							return true;
						}
					}catch(Exception se){
						//BugInfoWrint.Print(se);
					}
				}
				return false;
			}catch(Exception se){
				BugInfoWrint.Print(se);
			}
		}
		return false;
	}
}
